package com.sdleyou.treepro.common.service.impl;

import com.sdleyou.treepro.common.exception.ServiceException;
import com.sdleyou.treepro.common.model.dao.CertificateDO;
import com.sdleyou.treepro.common.model.dao.UserDO;
import com.sdleyou.treepro.common.model.dao.UserMissionDO;
import com.sdleyou.treepro.common.model.enums.ErrorCodeEnum;
import com.sdleyou.treepro.common.model.enums.RedisLockEnum;
import com.sdleyou.treepro.common.model.vo.CertificateVO;
import com.sdleyou.treepro.common.model.vo.OrderVO;
import com.sdleyou.treepro.common.model.vo.UserVO;
import com.sdleyou.treepro.common.service.CertificateManager;
import com.sdleyou.treepro.common.service.OrderManager;
import com.sdleyou.treepro.common.service.UserManager;
import com.sdleyou.treepro.common.utils.DateUtil;
import com.sdleyou.treepro.common.utils.HttpClientUtil;
import com.sdleyou.treepro.common.utils.IdGen;
import com.sdleyou.treepro.system.payment.UserConstantInterface;
import net.sf.json.JSONObject;
import org.apache.http.util.TextUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class CertificateManagerImpl implements CertificateManager {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private OrderManager orderManager;
    @Autowired
    private UserManager userManager;
    @Autowired
    private RedissonClient redissonClient;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 用户证书信息
     * @param userId
     * @param type
     * @return
     */
    @Override
    public CertificateVO getCertificateInfo(String userId, String type) {
        Query query = new Query(Criteria.where("user_id").is(userId).and("c_type").is(type));
        CertificateDO certificateDO = mongoTemplate.findOne(query, CertificateDO.class);
        if(certificateDO==null){
            throw new ServiceException(ErrorCodeEnum.E800.code(), "证书不存在");
        }
        CertificateVO certificateVO = new CertificateVO();
        BeanUtils.copyProperties(certificateDO, certificateVO);
        return certificateVO;
    }

    /**
     * 生成证书
     */
    @Override
    public CertificateVO createCertificate(String userId, String type, Integer treeNum) {
        //获取内存锁
        RLock fairLock = redissonClient.getFairLock(RedisLockEnum.CERTIFICATE.name());
        try {
            boolean res = fairLock.tryLock(2, 10, TimeUnit.SECONDS);
            if (res) {
                Query query = new Query(Criteria.where("user_id").is(userId).and("c_type").is(type));
                CertificateDO certificateDO = mongoTemplate.findOne(query, CertificateDO.class);
                if(certificateDO==null){
                    Update update = new Update();
                    if("QMYW".equals(type)){
                        update.set("has_QMYW", true);
                    }else if("GTLH".equals(type)){
                        update.set("has_GTLH", true);
                    }
                    String certificate = getCertificate(userId, treeNum);
                    if(TextUtils.isEmpty(certificate)){
                        throw new Exception();
                    }
                    certificateDO = new CertificateDO();
                    certificateDO.setCImg(certificate);
                    certificateDO.setUserId(userId);
                    certificateDO.setCType(type);
                    certificateDO.setCId(IdGen.uuid());
                    certificateDO.setGmtCreate(DateUtil.getDateline());
                    certificateDO.setGmtModified(DateUtil.getDateline());
                    mongoTemplate.insert(certificateDO);

                    //更新用户状态
                    Query q = new Query(Criteria.where("user_id").is(userId));
                    update.set("gmt_modified", DateUtil.getDateline() + "");
                    mongoTemplate.updateFirst(q, update, UserDO.class);
                }
            }
        } catch (InterruptedException e) {
            logger.info("updateTotalTree 公平锁操作异常{}、{}", e.getStackTrace(), e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //解锁
            fairLock.unlock();
        }
        return null;
    }

    /**
     * 请求外网链接获取证书图片
     */
    private String getCertificate(String userId, Integer num){
        UserVO userVO = userManager.userInfo(userId);
        String url = "http://www.yiwuzhishu.cn/index.php/Home/Api/addCreateZsTy";
        Map<String, String> param = new HashMap<>();
        param.put("name", userVO.getRealName());
        param.put("sfz", userVO.getIdCardNum());
        param.put("phone", userVO.getPhone());
        param.put("num", num+"");
        param.put("code", "140100");
        param.put("leibie", "1");
        // 发送请求
        String postResult = HttpClientUtil.doPost(url, param);
        System.out.println(postResult);
        JSONObject jsonObject = JSONObject.fromObject(postResult);
        // 获取参数返回的
        String result = jsonObject.get("result").toString();
        if("ok".equals(result)){
            JSONObject message = jsonObject.getJSONObject("message");
            int type = message.getInt("type"); //1 荣誉证书 2、义务证书
            String img = message.getString("url");
            if(!TextUtils.isEmpty(img) && img.contains(",")){
                String[] split = img.split(",");
                img = split[split.length-1];
            }
            return img;
        }else{
            return null;
        }
    }

    /**
     * 扫描生成证书
     */
    @Override
    public void updateCertificate() {
        Query queryQM = new Query(Criteria.where("has_QMYW").is(false));
        List<UserDO> all = mongoTemplate.find(queryQM, UserDO.class);
        for (UserDO userDO : all){
            if(userDO != null){
                if(!userDO.getHasQMYW()){
                    Integer totalTree = userDO.getTotalTree();
                    if(totalTree >= 3){
                        if(!userDO.getHasQMYW()){
                            System.out.println("3");
                            createCertificate(userDO.getUserId(), "QMYW", 3);
                        }
                    }else {
                        if(!userDO.getHasQMYW()){
                            List<OrderVO> allOrder = orderManager.getAllOrder(userDO.getUserId());
                            Double totalMoney = 0.0;
                            for (OrderVO orderVO: allOrder) {
                                Double orderAmount = orderVO.getOrderAmount();
                                totalMoney += orderAmount;
                            }
                            Double money = new Double("30.0");
                            if(totalMoney.compareTo(money)>=0){
                                System.out.println("30");
                                createCertificate(userDO.getUserId(), "QMYW", 3);
                            }
                        }
                    }
                }
            }
        }

        Query queryGT = new Query(Criteria.where("has_GTLH").is(false));
        all = mongoTemplate.find(queryGT, UserDO.class);
        for (UserDO userDO : all){
            if(userDO != null){
                if(!userDO.getHasGTLH()){
                    Integer totalTree = userDO.getTotalTree();
                    if(totalTree >= 6){
                        if(!userDO.getHasGTLH()){
                            System.out.println("6");
                            createCertificate(userDO.getUserId(), "GTLH", userDO.getTotalTree());
                        }
                    }else {
                        if(!userDO.getHasGTLH()){
                            List<OrderVO> allOrder = orderManager.getAllOrder(userDO.getUserId());
                            Double totalMoney = 0.0;
                            for (OrderVO orderVO: allOrder) {
                                Double orderAmount = orderVO.getOrderAmount();
                                totalMoney += orderAmount;
                            }
                            Double money = new Double("60.0");
                            if(totalMoney.compareTo(money)>=0){
                                System.out.println("60");
                                createCertificate(userDO.getUserId(), "GTLH", 6);
                            }
                        }
                    }
                }
            }
        }
    }
}



